#ifndef _MASSAGE_BSP_H_
#define _MASSAGE_BSP_H_

#include <stdint.h>
#include "massage_cfg.h"

#ifndef TRUE
  #define TRUE                          1
#endif

#ifndef FALSE
  #define FALSE                         0
#endif  

#define MSG_POS_NUM             		6
#define MSG_FOOT_POS_CMD 				0x01
#define MSG_LEG_POS_CMD					0x02
#define MSG_HIP_POS_CMD					0x04
#define MSG_LOIN_POS_CMD				0x08
#define MSG_BACK_POS_CMD 				0X10
#define MSG_HEAD_POS_CMD				0X20

typedef enum {
    MSG_POS_NONE = 0,
	MSG_POS_FOOT,   //脚
    MSG_POS_LEG,    //腿
	MSG_POS_HIP,    //座，臀
    MSG_POS_LOIN,   //腰
	MSG_POS_BACK,   //背
	MSG_POS_HEAD    //头
} msg_pos_t;

typedef enum {
	MSG_MODE_0 = 0,
    MSG_MODE_1,
    MSG_MODE_2,
    MSG_MODE_3,
	MSG_MODE_4,
	MSG_MODE_5,
	MSG_MODE_6,
	MSG_MODE_7,
	MSG_MODE_8,
	MSG_MODE_9,
	MSG_MODE_10
} msg_mode_t;

typedef enum {
	MSG_STRE_0 = 0,
    MSG_STRE_1,
    MSG_STRE_2,
    MSG_STRE_3,
	MSG_STRE_4,
	MSG_STRE_5,
	MSG_STRE_6,
	MSG_STRE_7,
	MSG_STRE_8,
	MSG_STRE_9,
	MSG_STRE_10
} msg_stre_t;

typedef enum {
   MSG_CLOSE = 0,
   MSG_OPEN
} msg_sta_t;

typedef enum {
   MSG_MANUAL = 0,
   MSG_AUTO
} msg_run_mode_t;

typedef enum {
   MSG_UNOVER = 0,
   MSG_OVER
} msg_oc_t;

typedef enum {
   NORMAL_MODE = 0,
   POINT_MODE,
   OC_CHECK_MODE
} msg_mode_oc_value_t;

typedef enum {
   M_SET_NONE = 0,
   M_SET_ON_OR_OFF,
   M_SET_RUN_MODE,
   M_SET_MANUAL_MODE,
   M_SET_STRE,
   M_SET_HEAD_EN,
   M_SET_TIME,
   M_SET_POINT
} msg_cmd_t;

typedef union {			
    struct {			
        uint8_t foot:1;
        uint8_t leg:1;
        uint8_t hip:1;
        uint8_t loin:1;
        uint8_t back:1;
        uint8_t head:1;
        uint8_t temp:2;			
    } pos;
    uint8_t pos_ctl;
} pos_ctl_t;

typedef struct {
    uint8_t mode[MSG_DEV_NUM];
    uint8_t work_sta[MSG_DEV_NUM];
    uint8_t work_time[MSG_DEV_NUM];
    uint8_t msg_pos_led[MSG_DEV_NUM];
} msg_info_t;

typedef struct {
    uint8_t stre;                       //the level of massage intensity
    uint8_t intensity;                  // massage intensity
    uint8_t intensity_backups;          // the backups of massage intensity
    uint8_t mode_sw_type;               // auto or manual 
    uint8_t mode;		                // massage mode
	uint8_t manual_mode;		        // manual setting	
	uint8_t manual_sw_mode_flag;	    // switch massage mode in manual mode	
    uint8_t suspend_flag;               // massage work flag
    uint8_t work_sta;                   // massage work status? open or close
    uint8_t fre_cnt;                    // massage work frequency
    uint8_t mode_type;                  // mode work type
	uint8_t mode2_sw_cnt;		        // mode2 switch timeout
	uint8_t head_en_flag; 	            // open head flag 
	uint8_t point_en_flag; 	            // work flag of massage point function
	uint8_t oc_flag ;			        // over current flag
	uint8_t msg_pos_led;		        // massage position open led
	uint8_t work_time;		            // massage work time
	uint8_t mode10_sw_stre_cnt;         // massage switch intensity of mode 10
    uint8_t msg_pos;                    // massage position of over current detection
    uint8_t msg_point_pos;              // massage position of point function
    uint8_t msg_pos_num;                // massage position number
    uint32_t auto_sw_cnt;               // auto switch massage mode
    uint32_t mode_sw_cnt;               // mode switch timeout 
	uint32_t mode2_sw_time;		        // mode2 switch time
	uint32_t mode1_sw_time_backups;	    // the backups of mode1 switch time
    uint32_t overflow_value;            // massage clk count over flow value
    pos_ctl_t pos;                      // massage pos work status? open or close
    pos_ctl_t oc;                       // massage pos over current status? yes or no
    pos_ctl_t oc_check;                 // massage pos over current check work status? open or close
    pos_ctl_t msg_install;              // massage pos installation status? yes or no
    pos_ctl_t msg_point;                // massage pos point work status? open or close
    struct {
        uint8_t time;
        uint32_t record;
        uint32_t cnt;
        uint32_t clk;
    } oc_check_tout;
} msg_para_t;

extern msg_para_t msg_para[MSG_DEV_NUM];

/**
 * @brief:  马达初始化,使用驱动必须调用
 */
void Msg_Init(void);

/**
 * @brief: 马达处理主程序, 需放入主循环中调用 
 */
void Msg_Process(void);

/**
 * @brief: 马达处理中断程序,主要用于控制马达的振动频率和强度，需放入定时器中断中调用
 */
void Msg_Int_Process(void);

/**
 * @brief: 马达操作函数 
 *
 * @param: dev:设备号 `MSG_DEV1 - MSG_DEV6`
 * @param: cmd:设置功能 `msg_cmd_t`
 * @param: arg:设置相对应功能状态值
 */
void Msg_Opt(uint8_t dev, msg_cmd_t cmd, void *arg);

/**
 * @brief: 获取状态信息 
 *
 * @param: Info: 详见`msg_info_t`
 */
void Msg_Get_Info(msg_info_t *info);                    

#if MSG_OVER_CURRENT_DETECTION
/**
 * @brief: 马达处理过流检测程序,主要用于马达的短路保护，需放入比较器中断中调用
 */
void Msg_Over_Current_Detection_Int_Process(void);
#endif 

#endif
